﻿using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering;

public class Lighting {

    // 定向光数量上限
    const int maxDirLightCount = 4;

    static int
        dirLightCountId = Shader.PropertyToID("_DirectionalLightCount"),
        dirLightColorsId = Shader.PropertyToID("_DirectionalLightColors"),
        dirLightDirectionsId = Shader.PropertyToID("_DirectionalLightDirections");

    static Vector4[]
        dirLightColors = new Vector4[maxDirLightCount],
        dirLightDirections = new Vector4[maxDirLightCount];
    
    const string bufferName = "Lighting";

    CommandBuffer buffer = new CommandBuffer {
        name = bufferName
    };
    
    // 剔除结果
    CullingResults cullingResults;
	
    public void Setup (ScriptableRenderContext context, CullingResults cullingResults) 
    {
        this.cullingResults = cullingResults; // 相机剔除的结果
        buffer.BeginSample(bufferName);
        SetupLights();
        buffer.EndSample(bufferName);
        context.ExecuteCommandBuffer(buffer);
        buffer.Clear();
    }

    /// <summary>
    /// 设置一个定向光
    /// </summary>
    void SetupDirectionalLight (int index, ref VisibleLight visibleLight) {
        dirLightColors[index] = visibleLight.finalColor;
        dirLightDirections[index] = -visibleLight.localToWorldMatrix.GetColumn(2);
    }

    /// <summary>
    /// 设置多个定向光
    /// </summary>
    void SetupLights()
    {
        NativeArray<VisibleLight> visibleLights = cullingResults.visibleLights; // 遍历可见光
        
        int dirLightCount = 0;
        for (int i = 0; i < visibleLights.Length; i++) 
        {
            VisibleLight visibleLight = visibleLights[i];

            // 只考虑定向光
            if (visibleLight.lightType == LightType.Directional)
            {
                SetupDirectionalLight(dirLightCount++, ref visibleLight);
                if (dirLightCount >= maxDirLightCount) {
                    break;
                }
            }
        }

        // 发送给GPU
        buffer.SetGlobalInt(dirLightCountId, dirLightCount);
        buffer.SetGlobalVectorArray(dirLightColorsId, dirLightColors);
        buffer.SetGlobalVectorArray(dirLightDirectionsId, dirLightDirections);
    }
}